home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / DOCS / PROGRAMM.TXT < prev    next >
Encoding:
Text File  |  1996-08-10  |  16.3 KB  |  352 lines

  1. XaAES - XaAES ain't AES
  2. ╜1995, Data Uncertain Software
  3. Written By Craig Graham.
  4. --
  5.  
  6.                         PROGRAMMERS DOCUMENTATION
  7.  
  8. This document is intended to give an overview of the underlying architecture
  9. of the XaAES GUI and details for XaAES specific programming.
  10.  
  11. NOTE: I should really move over to using sockets to speed things up instead of
  12. using pipes, but I'll have to write an installer to setup MiNT-net first
  13. (a worthy project....)
  14.  
  15. CONTENTS
  16.  
  17. 1. INTRODUCTION
  18. 2. ARCHITECTURE OF XAAES
  19. x. WIDGET HANDLERS
  20.  
  21. y. AES Extentions
  22.  
  23. 1) Introduction
  24. ----------------
  25.  
  26. After using MultiTOS, then AES4.1, I became frustrated at the lack of a decent
  27. GUI to use the real power of the MiNT kernal - X-Windows is all very
  28. well, but I cann't run GEM programs on it (and it's only black & white under
  29. MiNT). The W window system is ok but not widely used or available. The Mgr
  30. system (Bellcore Windows Manager) is seriously out of date (looks and feels
  31. rubbish), and again no GEM.
  32.  
  33. MultiTOS (even AES4.1) is too slow. Geneva didn't run with MiNT (and, having
  34. tried the new MiNT compatible version, I can say it wasn't very compatible
  35. - at least AES4.1 is quite stable, if a little slow). MagiC lives in a very
  36. fast, very small world all it's own (no networking support, few programs
  37. written to exploit it).
  38.  
  39. Firstly it is important to note that you can use & program XaAES without
  40. reading this - it provides a GEM compatible call interface via the
  41. standard GEM AES trap vector (trap 2).
  42.  
  43. More advanced programs can be produced using XaAES's non-blocking call
  44. interface which allows programs to make multiple calls without blocking
  45. to wait for replies from the AES.
  46.  
  47. Here's a few important general points about XaAES before we get technical:
  48.  
  49. o It works only with MiNT - the architecture was designed to use MiNT,
  50.   and so you must have it.
  51. o Being written especially for MiNT, it is a real MultiTasking GUI
  52.   that can run GEM programs, not a slow & unwieldy kludge like MultiTOS.
  53. o Groovy sculpted 3D interface.
  54. o Colour icon support for all machines.
  55. o No busy waiting in the AES.
  56. o Client-Server architecture.
  57. o The source is freely available. Anyone can change the code, if they send
  58.   patches to me with descriptions I'll included them into the next version.
  59.   In fact the whole point of this document is to give people enough info
  60.   to work on the code themselves.
  61. o Built with a 'real' C compiler (Lattice) not GNU
  62.   (in spite of the denisons of comp.sys.atari.st.tech and the gem-list
  63.   who wanted me to use GNU).
  64. o Extended fast interface for use by XaAES aware programs.
  65.   Extended call interface allows XaAES aware applications to make AES calls
  66.   without blocking to wait for replies they don't want, and to make multiple
  67.   AES calls (calls to the AES server are queued).
  68. o Works with NVDI (NOTE: NVDI must be loaded before XaAES in order to work,
  69.   otherwise strange things will happen).
  70.  
  71. 2) Architecture Of XaAES
  72. -------------------------
  73. XaAES is really three distinct comoponents:
  74.  
  75.  o XaAES GUI server. This is deals with all the windows & stuff. It uses the
  76.    existing VDI to produce it's graphics (and works fine with NVDI).
  77.    Most of the time the server is blocked reading from it's command pipe
  78.    - this means that unless it is actually doing something it doesn't use
  79.    any CPU time at all. The server runs completely in user mode, and so
  80.    can be pre-empted by MiNT at any time (unlike MultiTOS).
  81. o The GEM trap interface handler. This is actually part of the GUI server,
  82.    but it is run under the process id of the client (so I don't allow it
  83.    to access any of XaAES's data structures). It serves to serialise calls
  84.    to the AES, and drop them into a command pipe to the sercer. It then blocks
  85.    the client to wait for the AES server to service the command and reply.
  86.    This bit is quite dodgy as it makes OS calls from inside a trap
  87.    interupt, and I'm not altogether certain this was a legal thing to do.
  88.    It works, so it stays....
  89.    As of beta2, there has also been a direct call mechanism as well, which
  90.    allows certain functions to be called directly by the client in the way
  91.    normal GEM does, bypassing the command pipe altogether.
  92. o The 'moose.xdd' mouse device handler. This provides the mouse handling
  93.    services required by XaAES via a new MiNT device /dev/moose. This is
  94.    written in assembler (by James Cox), and although written especially
  95.    for XaAES, it is an independent program which could be used by other
  96.    applications as well as XaAES.
  97.  
  98. The XaAES GUI server manages the window system, and commumicates with the rest
  99. of the system via MiNT pipes. In order to run standard GEM programs, it also
  100. replaces the standard AES trap handler with a small routine that fields trapped
  101. calls and drops them into a server command pipe on behalf of the application
  102. (this is done transparently, the application see's it as being the ordinary
  103. GEM AES trap). This is slightly slower than accessing the command pipe directly,
  104. but is totally compatible with GEM.
  105.  
  106. 3) The XaAES Kernal
  107. ---------------------
  108.  
  109. The XaAES kernal consists of a small assembler routine to catch the TRAP#2 vector,
  110. another small C routine in handler.c which provides the interface to the XaAES pipe
  111. based client/server AES for normal GEM applications.
  112.  
  113. 3.1) The Command Pipe Interface
  114. ---------------------------------
  115.  
  116. Most commands go via the clients private command pipe.
  117.  
  118. The server must first be introduced to the client however, so there is a shared
  119. command pipe '/pipe/XaAES.cmd', where appl_init() will drop an XA_NEW_CLIENT message.
  120.  
  121. The server then responds by creating a bi-directionial command/reply pipe for the
  122. application. The client then uses this to communicate with the AES server kernal.
  123. (NOTE: The server uses Fselect() on all the client command pipes.)
  124. When an AES trap occurs, the handler drops the pointer to the parameter block into
  125. it's command pipe.
  126.  
  127. There are then 3 modes that the AES could have been called in.
  128.  
  129. If standard GEM emulation mode (trap2 entered with d0=0xc8) the handler then drops
  130. back into user mode and blocks whilst reading on the current process's reply pipe.
  131. This allows other processes to execute whilst XaAES is performing AES functions
  132. (the XaAES server runs wholely in user mode so it's more MiNT-friendly than
  133. MultiTOS). The server writes back to the clients reply pipe with the reply when
  134. it has serviced the command - this unblocks the client which then returns from
  135. the exception.
  136.  
  137. If NOREPLY mode is used, the AES doesn't block the calling process to wait
  138. for a reply - and indeed, won't generate one.
  139.  
  140. If NOBLOCK mode is used, the AES doesn't block the calling process - but does
  141. place the result in the client's reply pipe. The client is then expected to
  142. handle it's own reply pipe. This allows multiple AES calls to be made without
  143. blocking a process, so an app could make all it's GEM initialisation calls
  144. at one go, then go on to do it's internal initialisation before coming back
  145. to see if the AES has serviced it's requests (less blocking in the client,
  146. and better multitasking).
  147. The result will be a short with the low byte being one of:
  148.    XA_OK              - The op-code was supported & was executed
  149.    XA_UNIMPLEMENTED   - You may have used a valid op-code, but XaAES doesn't
  150.                         yet support it.
  151.    XA_ILLEGAL         - The op-code was invalid in the first place, or there
  152.                         was some other problem with the parameters....
  153.    XA_T_WAIT          - Re-select for a evnt_timer format timeout
  154.    XA_M_WAIT          - Re-select for a evnt_multi format timeout
  155.  
  156. For either XA_T_WAIT or XA_M_WAIT, the upper 3 bytes will contain a timeout
  157. value. This should be multiplied by 16 to get the timeout in milliseconds:
  158.  
  159. So, you would make the call then get the response using this method:
  160.       /* Do some GEM call here */
  161.       Fread(reply_pipe_handle,sizeof(short),&response);
  162.       timeout=response&0xfff0;
  163.       response&=0xf;
  164.       if ((response==XA_T_WAIT)||(response==XA_M_WAIT))
  165.       {
  166.          select_mask=1L<<reply_pipe_handle;
  167.          timeout=Fselect(timeout,&select_mask,NULL,NULL);
  168.          if (!timeout)
  169.             /* Command timed out */
  170.          else
  171.             /* Command didn't time out */
  172.       }
  173.  
  174. You can use NOBLOCK mode in conjunction with evnt_multi() to do nifty tricks
  175. like using Fselect() to wait for AES events and serial data, or perhaps listen
  176. to a socket, all at the same time......
  177.  
  178. NOTE: The reply pipe is opened on behalf of the client by appl_init(). The file handle
  179. can be found either by calling appl_pipe() from the XaAESLIB extention library, or
  180. from the application's global array at global[12].
  181.  
  182. The main kernal handler is in kernal.c : void kernal(void);
  183.  
  184. When an AES function packet is read from the command pipe, and the op-code is
  185. used to call an AES function handler routine via the Ktable[] array. A NULL
  186. in this array indicates an un-implemented function, otherwise it contains a
  187. pointer to an 'AESroutine' type function. These functions are always of type:
  188.  
  189.    short XA_objc_draw(short clnt_pid, AESPB *pb) { }
  190.  
  191. The pb parameter (obviously) always points to the AES parameter block for the
  192. call, and clnt_pid is the MiNT process id of the client making the call.
  193. NOTE: In XaAES MiNTpid==AESid.
  194.  
  195. Details of a client can be found in the XA_CLIENT clients[];  array
  196. (index on clnt_pid).
  197.  
  198. The return value of a call is crucial - if the function returns TRUE (1) then
  199. the kernal will write to the clients reply pipe 'u:\pipe\XaClnt.<PID>' to unblock
  200. the process (in NOBLOCK or NOREPLY modes, the client won't have blocked anyway).
  201. If FALSE (0) is returned by the function, then the kernal leaves the client blocked
  202. - this is how functions like evnt_multi() block to wait for an event. The occurance
  203. of the event causes the value to be written to the reply pipe to unblock the client.
  204.  
  205. x) Widget Handlers
  206. -------------------
  207. XaAES uses callback functions to handle all window widgets. These are refered
  208. to as 'behaviours'. Each widget has 4 behaviours - CLICK, DCLICK, DRAG &
  209. DISPLAY. These are held in an XA_WIDGET structure (see the file XA_TYPES.H).
  210. Each window has a set of these structures associated with it. The advantage
  211. of this is that the behaviour of a widget can be modified on a window by window
  212. basis (how it's displayed, what happens when it's clicked on, etc).
  213.  
  214. CLICK  - called whenever the user single clicks on the widget
  215. DCLICK - called when the user double clicks on the widget
  216. DRAG   - called with the mouse button down when the user clicks and holds the
  217.          button down on the widget
  218. DISPLAY- called to display the widget whenever the window is redrawn or the
  219.          status of the widget changes. XaAES will set up appropriate clip
  220.          rectangles before calling this behaviour, so all it has to do is draw
  221.          the thing - taking into account the status of the widget (selected,
  222.          etc).
  223.  
  224. Not all widgets will need all the behaviours. For example, the standard GEM
  225. closer widget has only CLICK and DISPLAY behaviours, you cann't drag the closer
  226. and a double click does nothing, so they are left as NULL to signify that
  227. they aren't valid.
  228.  
  229. GENERAL PRINCIPLE: If a widget isn't to behave in a certain way, set that
  230. behaviour to NULL.
  231.  
  232. A widget handler is passed two parameters when it is called :
  233.    XA_WINDOW *wind   - the window which the widget is a part of
  234.    XA_WIDGET *widg - the widget descriptor
  235.  
  236. These contain all the info a widget needs.
  237.  
  238. The handler itself should be of this type:
  239.  
  240.    short widget_handler_routine(XA_WINDOW *wind, XA_WIDGET *widg) { }
  241.  
  242. The XA_WIDGET structure looks like this:
  243.  
  244.    typedef struct xa_widget {
  245.       XA_WIDGET_LOCATION loc;    // Location of widget relative to window extents
  246.       WidgetCallback behaviour[COUNT_XACB];  // Callback function pointers to the behaviours of the widget
  247.       XA_WIDGET_STATUS stat;     // Current status (selected, etc)
  248.       short w,h;              // dimensions
  249.       short click_x,click_y;     // If we are displaying because we've been clicked on, this is the location
  250.                            // of the click (this is only used by the slider widget really)
  251.       void *stuff;            // Pointer to widget dependant context data, if any
  252.    } XA_WIDGET;
  253.  
  254. The behaviour[] array contains pointers to all the behaviours for the widget.
  255.  
  256. w & h define the size of the widget - used to detect mouse events on the widget.
  257. When a mouse event occurs, the click_x & click_y values are filled in with the
  258. location of the click event prior to calling the widget handler.
  259.  
  260. All widgets have relative locations like X-Windows widgets (attribute 'loc').
  261. This is useful, as you can specify a widget as (RB, 1, 1) and it will always be
  262. displayed starting with it's coords in the bottom-right of the window. Possible
  263. relative coords are:
  264.  
  265.    LT : top left
  266.    CT : centred top (y relative to top, x recalculated to be window width / 2)
  267.    RT : top right
  268.    LB : bottom left
  269.    CB : centred bottom
  270.    RB : bottom right
  271.  
  272. An example use of this is the SIZER widget, which always keeps the same location
  273. relative to the bottom-right of the window, even when the window moves & changes
  274. size.
  275. The utility routine
  276.  
  277.    void rp_2_ap(XA_WINDOW *wind, XA_WIDGET *widg, short *x, short *y);
  278.  
  279. changes relative coords into absolute screen coordinates (returned in x & y).
  280.  
  281. When displaying, a widget should check it's state attribute 'stat' (normally
  282. XAW_PLAIN). If this is set to XAW_SELECTED then the widget should display
  283. itself in some 'selected' form - anything will do, just invert it like
  284. old GEM, or do a 3D push like AES4, maybe do some little animations like
  285. my default widget set does.
  286.  
  287. The final element of the XA_WIDGET structure is void *stuff; this is provided
  288. so certain widgets can have extra information kept with them - the scroll bars
  289. for instance keep a pointer to an XA_SLIDER_WIDGET structure here to maintain
  290. their size & position information.
  291.  
  292. It is intended that a user program in the know will be able to change the
  293. default behaviours of it's own window widgets, so a desktop could change
  294. the CLICK behaviour of the close widget for directory windows to make the
  295. window go back up a level instead of sending a WM_CLOSED, and perhaps display
  296. as a << arrow instead of a closer box.
  297.  
  298. User programs can also add their own custom widgets to a window, and they will
  299. behave in exactly the same way as the standard GEM widgets (the same behaviour
  300. based system).
  301.  
  302. Widgets should be informative and 'nice', so the XaAES versions of the standard
  303. GEM widgets (CLOSE, RESIZE, etc) are implemented as colour bitmaps (designed
  304. using Interface - get it it's cool) with seperate 'selected' images. This allows
  305. the CLOSE widget to display as an ordinary looking button, but get a little red
  306. alert sign with a '!' in it when you click on it.
  307.  
  308. y. AES EXTENSIONS
  309. -------------------
  310.  
  311. XaAES provides several extensions to the standard AES that provide more features.
  312. This section details exactly what these features are. Where possible, I've tied
  313. up with the oAESis authors to get support for these features in two AES's.
  314.  
  315. The file XAAESLIB.H provides bindings for the extended functions.
  316.  
  317. y.1 appl_init()
  318. ----------------
  319. The file handle of the clients command/reply pipe is available in global[12].
  320.  
  321. y.2 shel_write()
  322. -----------------
  323. We've extended shel_write() to support the concept of a multi-user system provided
  324. by MiNT.
  325.  
  326. When a program uses shel_write to launch a child, the default behaviour
  327. (under XaAES) is that the 'AES child' inherits the user id & group id of the
  328. process that launched it.
  329.  
  330. An extension to the AES4.0 shel_write() mode 0 is provided in the form of:
  331.  
  332.    #define SW_UID 0x1000   /* Set user id of launched child */
  333.    #define SW_GID 0x2000   /* Set group id of launched child */
  334.  
  335.    typedef struct _xshelw {
  336.       char *newcmd;
  337.       LONG psetlimit;
  338.       LONG prenice;
  339.       char *defdir;
  340.       char *env;
  341.       short uid;            /* New child's UID */
  342.       short gid;            /* New child's GID */
  343.    } XSHELW;
  344.  
  345. This is used in the same way as the AES4.0 SHELW structure and is compatible - using
  346. the extended structure won't kill AES4.0, the UID/GID fields will simply be ignored.
  347. The extra fields uid & gid allow you to explicitly set the child's user & group id.
  348.  
  349. NOTE: This was agreed with the authors of Geneva and oAESis as well as XaAES....
  350.  
  351.  
  352.